from core.app.app_config.easy_ui_based_app.agent.manager import AgentConfigManager
from core.tools.tool_manager import ToolManager
from extensions.ext_database import db
from models.account import Account
from models.model import App, Conversation, EndUser, Message, MessageAgentThought


class AgentService:
    @classmethod
    def get_agent_logs(cls, app_model: App, 
                       conversation_id: str,
                       message_id: str) -> dict:
        """
        Service to get agent logs
        """
        conversation: Conversation = db.session.query(Conversation).filter(
            Conversation.id == conversation_id,
            Conversation.app_id == app_model.id,
        ).first()

        if not conversation:
            raise ValueError(f"Conversation not found: {conversation_id}")

        message: Message = db.session.query(Message).filter(
            Message.id == message_id,
            Message.conversation_id == conversation_id,
        ).first()

        if not message:
            raise ValueError(f"Message not found: {message_id}")
        
        agent_thoughts: list[MessageAgentThought] = message.agent_thoughts

        if conversation.from_end_user_id:
            # only select name field
            executor = db.session.query(EndUser, EndUser.name).filter(
                EndUser.id == conversation.from_end_user_id
            ).first()
        else:
            executor = db.session.query(Account, Account.name).filter(
                Account.id == conversation.from_account_id
            ).first()
        
        if executor:
            executor = executor.name
        else:
            executor = 'Unknown'

        result = {
            'meta': {
                'status': 'success',
                'executor': executor,
                'start_time': message.created_at.isoformat(),
                'elapsed_time': message.provider_response_latency,
                'total_tokens': message.answer_tokens + message.message_tokens,
                'agent_mode': app_model.app_model_config.agent_mode_dict.get('strategy', 'react'),
                'iterations': len(agent_thoughts),
            },
            'iterations': [],
            'files': message.files,
        }

        agent_config = AgentConfigManager.convert(app_model.app_model_config.to_dict())
        agent_tools = agent_config.tools

        def find_agent_tool(tool_name: str):
            for agent_tool in agent_tools:
                if agent_tool.tool_name == tool_name:
                    return agent_tool

        for agent_thought in agent_thoughts:
            tools = agent_thought.tools
            tool_labels = agent_thought.tool_labels
            tool_meta = agent_thought.tool_meta
            tool_inputs = agent_thought.tool_inputs_dict
            tool_outputs = agent_thought.tool_outputs_dict
            tool_calls = []
            for tool in tools:
                tool_name = tool
                tool_label = tool_labels.get(tool_name, tool_name)
                tool_input = tool_inputs.get(tool_name, {})
                tool_output = tool_outputs.get(tool_name, {})
                tool_meta_data = tool_meta.get(tool_name, {})
                tool_config = tool_meta_data.get('tool_config', {})
                if tool_config.get('tool_provider_type', '') != 'dataset-retrieval':
                    tool_icon = ToolManager.get_tool_icon(
                        tenant_id=app_model.tenant_id,
                        provider_type=tool_config.get('tool_provider_type', ''),
                        provider_id=tool_config.get('tool_provider', ''),
                    )
                    if not tool_icon:
                        tool_entity = find_agent_tool(tool_name)
                        if tool_entity:
                            tool_icon = ToolManager.get_tool_icon(
                                tenant_id=app_model.tenant_id,
                                provider_type=tool_entity.provider_type,
                                provider_id=tool_entity.provider_id,
                            )
                else:
                    tool_icon = ''

                tool_calls.append({
                    'status': 'success' if not tool_meta_data.get('error') else 'error',
                    'error': tool_meta_data.get('error'),
                    'time_cost': tool_meta_data.get('time_cost', 0),
                    'tool_name': tool_name,
                    'tool_label': tool_label,
                    'tool_input': tool_input,
                    'tool_output': tool_output,
                    'tool_parameters': tool_meta_data.get('tool_parameters', {}),
                    'tool_icon': tool_icon,
                })

            result['iterations'].append({
                'tokens': agent_thought.tokens,
                'tool_calls': tool_calls,
                'tool_raw': {
                    'inputs': agent_thought.tool_input,
                    'outputs': agent_thought.observation,
                },
                'thought': agent_thought.thought,
                'created_at': agent_thought.created_at.isoformat(),
                'files': agent_thought.files,
            })

        return result